package com.poly.cms.service.impl;

import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.poly.cms.domain.CmsChannel;
import com.poly.cms.mapper.CmsChannelMapper;
import com.poly.cms.pojo.dto.CmsChannelDTO;
import com.poly.cms.pojo.query.CmsChannelQuery;
import com.poly.cms.pojo.vo.CmsChannelVO;
import com.poly.cms.service.ICmsChannelService;
import com.poly.common.core.domain.R;
import com.poly.common.core.tools.utils.Func;
import com.poly.common.core.utils.ConvertUtils;
import com.poly.system.RemoteUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 频道信息Service业务层处理
 *
 * @author poly
 * @date 2023-10-25
 */
@Service
public class CmsChannelServiceImpl extends ServiceImpl<CmsChannelMapper, CmsChannel> implements ICmsChannelService {

    @Autowired
    private RemoteUserService remoteUserService;
    /**
     * 获取查询对象
     *
     * @param query
     * @return
     */
    public LambdaQueryWrapper<CmsChannel> getWrapper(CmsChannelQuery query) {
        LambdaQueryWrapper<CmsChannel> wrapper = null;
        if (Func.isNotEmpty(query)) {
            wrapper = Wrappers.<CmsChannel>lambdaQuery();
            if (Func.isNotEmpty(query.getId())) {
                wrapper.eq(CmsChannel::getId, query.getId());
            }
            if (Func.isNotEmpty(query.getChannelName())) {
                wrapper.like(CmsChannel::getChannelName, query.getChannelName());
            }
            if (Func.isNotEmpty(query.getEnglishName())) {
                wrapper.like(CmsChannel::getEnglishName, query.getEnglishName());
            }
            if (Func.isNotEmpty(query.getParentId())) {
                wrapper.eq(CmsChannel::getParentId, query.getParentId());
            }
            if (Func.isNotEmpty(query.getSort())) {
                wrapper.eq(CmsChannel::getSort, query.getSort());
            }
            if (Func.isNotEmpty(query.getTarget())) {
                wrapper.eq(CmsChannel::getTarget, query.getTarget());
            }
            if (Func.isNotEmpty(query.getGroupName())) {
                wrapper.like(CmsChannel::getGroupName, query.getGroupName());
            }
            if (Func.isNotEmpty(query.getOpenLike())) {
                wrapper.eq(CmsChannel::getOpenLike, query.getOpenLike());
            }
            if (Func.isNotEmpty(query.getOpenComment())) {
                wrapper.eq(CmsChannel::getOpenComment, query.getOpenComment());
            }
            if (Func.isNotEmpty(query.getLinkUrl())) {
                wrapper.eq(CmsChannel::getLinkUrl, query.getLinkUrl());
            }
            if (Func.isNotEmpty(query.getStatus())) {
                wrapper.eq(CmsChannel::getStatus, query.getStatus());
            }
            if (Func.isNotEmpty(query.getImage())) {
                wrapper.eq(CmsChannel::getImage, query.getImage());
            }
        }
        return wrapper;
    }

    /**
     * 查询频道信息
     *
     * @param id 频道信息主键
     * @return 频道信息
     */
    @Override
    public CmsChannel get(Long id) {
        return getById(id);
    }


    /**
     * 查询频道信息
     *
     * @param id 频道信息主键
     * @return 频道信息
     */
    @Override
    public CmsChannelVO getVO(Long id) {
        CmsChannelVO vo = Func.copyProperties(this.get(id), CmsChannelVO.class);
        Map<Long, String> userNameMap = R.getData( remoteUserService.getUserNameMap(Arrays.asList(vo.getCreateBy(),vo.getUpdateBy())));
        if(Func.isNotEmpty(userNameMap)){
            vo.setCreateName(userNameMap.get(vo.getCreateBy()));
            vo.setUpdateName(userNameMap.get(vo.getUpdateBy()));
        }
        return vo;
    }

    /**
     * 查询频道信息列表
     *
     * @param query 频道信息
     * @return 频道信息
     */
    @Override
    public List<CmsChannelVO> queryList(CmsChannelQuery query) {
        List<CmsChannelVO> channelVOS = baseMapper.queryList(query);
        List<Long> userIds = channelVOS.stream().map(CmsChannelVO::getCreateBy).collect(Collectors.toList());
        userIds.addAll(channelVOS.stream().map(CmsChannelVO::getUpdateBy).collect(Collectors.toList()));
        Map<Long, String> userNameMap = R.getData(remoteUserService.getUserNameMap(userIds.stream().distinct().collect(Collectors.toList())));
        if(Func.isNotEmpty(userNameMap)) {
            channelVOS.forEach(i -> {
                i.setCreateName(userNameMap.get(i.getCreateBy()));
                i.setUpdateName(userNameMap.get(i.getUpdateBy()));
            });
        }
        return channelVOS;
    }

    /**
     * 新增频道信息
     *
     * @param dto 频道信息
     * @return 结果
     */
    @Override
    public boolean add(CmsChannelDTO dto) {
        CmsChannel one = this.getOne(new LambdaQueryWrapper<CmsChannel>().like(CmsChannel::getChannelName, dto.getChannelName())
                .or().like(CmsChannel::getEnglishName, dto.getEnglishName()));
        Assert.isTrue(Func.isEmpty(one),"频道名称或频道英文名称重复！");
        CmsChannel entity = ConvertUtils.convert(dto, CmsChannel.class);
        entity.setId(null);
        return save(entity);
    }

    /**
     * 修改频道信息
     *
     * @param dto 频道信息
     * @return 结果
     */
    @Override
    public boolean update(CmsChannelDTO dto) {
        CmsChannel one = this.getOne(new LambdaQueryWrapper<CmsChannel>()
                .ne(CmsChannel::getId,dto.getId())
                .and(i -> i.like(CmsChannel::getChannelName, dto.getChannelName())
                        .or().like(CmsChannel::getEnglishName, dto.getEnglishName())));
        Assert.isTrue(Func.isEmpty(one),"频道名称或频道英文名称重复！");
        CmsChannel entity = ConvertUtils.convert(dto, CmsChannel.class);
        return updateById(entity);
    }

    /**
     * 批量删除频道信息
     *
     * @param ids 需要删除的频道信息主键
     * @return 结果
     */
    @Override
    public boolean deleteByIds(Long[] ids) {
        for (Long id : ids) {
            List<CmsChannel> channels = this.list(new LambdaQueryWrapper<CmsChannel>().eq(CmsChannel::getParentId, id));
            Assert.isTrue(Func.isEmpty(channels),"栏目【" + this.get(id).getChannelName() +"】有子栏目，无法删除！");
//            List<CmsContent> list = contentService.getByChannelId(id);
//            Assert.isTrue(Func.isEmpty(list),"栏目【" + this.get(id).getChannelName() +"】有内容关联，无法删除！");
        }
        return removeBatchByIds(Arrays.asList(ids));
    }

    /**
     * 删除频道信息信息
     *
     * @param id 频道信息主键
     * @return 结果
     */
    @Override
    public boolean deleteById(Long id) {
        return removeById(id);
    }

    @Override
    public List<CmsChannelVO> listTree(CmsChannelQuery qo) {
        List<CmsChannelVO> list = Func.copyProperties(this.list(getWrapper(qo)),CmsChannelVO.class);
        List<Long> userIds = list.stream().filter(p->Func.isNotEmpty(p.getUpdateBy())).map(CmsChannelVO::getCreateBy).collect(Collectors.toList());
        userIds.addAll(list.stream().filter(p->Func.isNotEmpty(p.getCreateBy())).map(CmsChannelVO::getUpdateBy).collect(Collectors.toList()));
        Map<Long, String> userNameMap = R.getData(remoteUserService.getUserNameMap(userIds.stream().distinct().collect(Collectors.toList())));
        if(Func.isNotEmpty(userNameMap)) {
            list.forEach(i -> {
                i.setCreateName(userNameMap.get(i.getCreateBy()));
                i.setUpdateName(userNameMap.get(i.getUpdateBy()));
            });
        }
        return getChildPerms(list,0L);
    }

    public List<CmsChannelVO> getChildPerms(List<CmsChannelVO> list, Long parentId) {
        List<CmsChannelVO> cmsChannelVOS = new ArrayList<>();
        if(Func.isNotEmpty(list)){
            for (CmsChannelVO channel : list) {
                if (channel.getParentId().equals(parentId)) {
                    List<CmsChannelVO> children = recursion(list, channel);
                    channel.setChildren(Func.isEmpty(children) ? null : children);
                    cmsChannelVOS.add(channel);
                }
            }
        }
        return cmsChannelVOS;
    }


    private List<CmsChannelVO> recursion(List<CmsChannelVO> list, CmsChannelVO parent) {
        List<CmsChannelVO> result = Lists.newArrayList();
        for (CmsChannelVO channel : list) {
            if (channel.getParentId().equals(parent.getId())) {
                List<CmsChannelVO> children = recursion(list, channel);
                channel.setChildren(Func.isEmpty(children) ? null : children);
                result.add(channel);
            }
        }
        return result;
    }
}
